/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package tools;

import com.openbrew.openbrewrf.FinishedGoodsInventory;
import com.openbrew.openbrewrf.PackageType;
import java.util.Date;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

/**
 *
 * @author chapmand
 */
public class FGITools {
    private final float GALLON = (float)0.032258;
    /***************************************************************************
     * Processes all actions needed for an FGI fill.
     **************************************************************************/
    private FinishedGoodsInventory getFGI(final EntityManager en, final int fgiid){
        TypedQuery<FinishedGoodsInventory> query = en.createQuery(
                "SELECT f FROM FinishedGoodsInventory f WHERE f.fgiid = ?1"
                , FinishedGoodsInventory.class);
        query.setParameter(1, fgiid);
        FinishedGoodsInventory fgi = query.getSingleResult();
        return fgi;
    }
    
    /***************************************************************************
     * Processes keg split.
     * @param en
     * @param oldFGIid
     * @param oldQty
     * @param newFGIid
     * @param newQty
     * @return 
     **************************************************************************/
    public String doFGIKegSplit(final EntityManager en, final int oldFGIid
        , final int oldQty, final int newFGIid, final int newQty){
        final FinishedGoodsInventory oldFGI = getFGI(en, oldFGIid);
        final FinishedGoodsInventory newFGI = getFGI(en, newFGIid);
        final double oldTot = (double)oldFGI.getFGIPackageID().getNumItems() 
                * (double)oldFGI.getFGIPackageID().getPackageTypeVol()
                * (double)oldQty;
        final double newTot = (double)newFGI.getFGIPackageID().getNumItems() 
                * (double)newFGI.getFGIPackageID().getPackageTypeVol()
                * (double)newQty;
        final double diff = (oldTot - newTot);
        if((diff<=(double)0.1) && (diff>=(double)-0.1)){
            //this is a valid split, proceed.
            InventoryModifiers im = new InventoryModifiers();
            im.doFGIAddition(en, newFGI, newQty);
            im.doFGIRemovalWithoutAllocation(en, oldFGI.getFgiid(), (long)oldQty);
            en.getEntityManagerFactory().getCache().evictAll();
            return "Split Successful!";
        } else {
            return "Error!, Packages do not equal one another.";
        }
    }
    
    /***************************************************************************
     * Processes all actions needed for a serving tank split..
     * @param en
     * @param oldFGIid
     * @param newFGIid
     * @param newQty
     * @return 
     **************************************************************************/
    public String doFGIVesselSplit(final EntityManager en, final int oldFGIid
            , final int newFGIid, final int newQty){
        final FinishedGoodsInventory oldFGI = getFGI(en, oldFGIid);
        if(oldFGI.getFGIPackageID().isServingVessel()){
            final FinishedGoodsInventory newFGI = getFGI(en, newFGIid);
            final double newTot = (double)newFGI.getFGIPackageID().getNumItems() 
                * (double)newFGI.getFGIPackageID().getPackageTypeVol()
                * (double)newQty;
            InventoryModifiers im = new InventoryModifiers();
            im.doFGIAddition(en, newFGI, newQty);
            im.doFGIServingTankRemovalWithoutAllocation(en, oldFGIid, (float)newTot);
            en.getEntityManagerFactory().getCache().evictAll();
            return "Split Successful!";
        } else {
            return "Error!, Originating vessel must be a serving vessel.";
        }
    }
    
    /***************************************************************************
     * Do a FGI addition.
     * @param en - Entity Manager
     * @param fgiid - FGI id being modified.
     * @param qty - quantity of FGI being added.
     * @param brewid - id of brew the FGI was filled from.
     * @param employeeID - id of employee who bottled beer.
     * @param date
     **************************************************************************/
    public void doFGIBottleAddition(final EntityManager en, final int fgiid
            , final int qty, final int brewid, final int employeeID, final Date date){
        if(fgiid!=0){
            TypedQuery<FinishedGoodsInventory> query = en.createQuery(
                    "SELECT f FROM FinishedGoodsInventory f WHERE f.fgiid = ?1"
                    , FinishedGoodsInventory.class);
            query.setParameter(1, fgiid);
            FinishedGoodsInventory fgi = query.getSingleResult();
            //Get the volume of beer moved.
            final double volumeMoved = calcVol(fgi, qty);
            
            //First update FGI and supplies.
            InventoryModifiers im = new InventoryModifiers();
            im.doFGIAddition(en, fgi, qty);
            
            //Update the tank volume.
            final BrewsTools bt = new BrewsTools();
            bt.updateTankVolumeForBottleMovement(en, volumeMoved, brewid);
            
            //Insert a movement based on fgi.
            final MovementTools mt = new MovementTools();
            mt.insertBottleMovement(en, volumeMoved, brewid, employeeID, date);
        }
    }
    
    /***************************************************************************
     * Do a FGI Keg addition.
     * @param en - Entity Manager
     * @param fgiid - FGI id being modified.
     * @param qty - quantity of FGI being added.
     * @param brewid - id of brew the FGI was filled from.
     * @param employeeID - id of employee who kegged beer.
     * @param date
     **************************************************************************/
    public void doFGIKegAddition(final EntityManager en, final int fgiid
            , final int qty, final int brewid, final int employeeID, final Date date){
        if(fgiid!=0){
            TypedQuery<FinishedGoodsInventory> query = en.createQuery(
                    "SELECT f FROM FinishedGoodsInventory f WHERE f.fgiid = ?1"
                    , FinishedGoodsInventory.class);
            query.setParameter(1, fgiid);
            FinishedGoodsInventory fgi = query.getSingleResult();
            //Get the volume of beer moved.
            final double volumeMoved = calcVol(fgi, qty);
            
            //First update FGI and supplies.
            InventoryModifiers im = new InventoryModifiers();
            im.doFGIAddition(en, fgi, qty);
            
            //Update the tank volume.
            final BrewsTools bt = new BrewsTools();
            bt.updateTankVolumeForKegMovement(en, volumeMoved, brewid);
            
            //Insert a movement based on fgi.
            final MovementTools mt = new MovementTools();
            mt.insertKegMovement(en, volumeMoved, brewid, employeeID, date);
        }
    }
    
    /***************************************************************************
     * Do a Serving Vessel addition.
     * @param en - Entity Manager
     * @param fgiid - FGI id being modified.
     * @param qty - quantity of FGI being added.
     * @param brewid - id of brew the FGI was filled from.
     * @param employeeID - id of employee who kegged beer.
     * @param date
     **************************************************************************/
    public void doFGIServingVesselAddition(final EntityManager en, final int fgiid
            , final float qty, final int brewid, final int employeeID, final Date date){
        if(fgiid!=0){
            TypedQuery<FinishedGoodsInventory> query = en.createQuery(
                    "SELECT f FROM FinishedGoodsInventory f WHERE f.fgiid = ?1"
                    , FinishedGoodsInventory.class);
            query.setParameter(1, fgiid);
            FinishedGoodsInventory fgi = query.getSingleResult();
            //Get the volume of beer moved.
            final double volumeMoved = (double)qty;
            
            //First update FGI and supplies.
            InventoryModifiers im = new InventoryModifiers();
            im.doFGIServingVesselAddition(en, fgi, qty);
            
            //Update the tank volume.
            final BrewsTools bt = new BrewsTools();
            bt.updateTankVolumeForKegMovement(en, volumeMoved, brewid);
            
            //Insert a movement based on fgi.
            final MovementTools mt = new MovementTools();
            mt.insertKegMovement(en, volumeMoved, brewid, employeeID, date);
        }
    }
    
    /***************************************************************************
     * Do a FGI Barreled Beer addition.
     * @param en - Entity Manager
     * @param fgiid - FGI id being modified.
     * @param qty - quantity of FGI being added.
     * @param bcsid - id of brew the FGI was filled from.
     * @param employeeID - id of employee who bottled beer.
     **************************************************************************/
    public void doFGIBarreledAddition(final EntityManager en, final int fgiid
            , final int qty, final int bcsid, final int employeeID){
        if(fgiid!=0){
            TypedQuery<FinishedGoodsInventory> query = en.createQuery(
                    "SELECT f FROM FinishedGoodsInventory f WHERE f.fgiid = ?1"
                    , FinishedGoodsInventory.class);
            query.setParameter(1, fgiid);
            FinishedGoodsInventory fgi = query.getSingleResult();
            //Get the volume of beer moved.
            final double volumeMoved = calcVol(fgi, qty);
            
            //First update FGI and supplies.
            InventoryModifiers im = new InventoryModifiers();
            im.doFGIAddition(en, fgi, qty);
            
            //Update the tank volume.
            final BarrelConditioningTools bcst = new BarrelConditioningTools();
            bcst.updateTankVolumeForMovement(en, volumeMoved, bcsid);
            
            //Insert a movement based on fgi.
            final MovementTools mt = new MovementTools();
            if(fgi.getFGIPackageID().getPackageTypeVol() < GALLON){
                //Make it a bottle movement.
                mt.insertBarrelBottleMovement(en, volumeMoved, bcsid, employeeID);
            } else {
                //Make it a keg movement.
                mt.insertBarrelKegMovement(en, volumeMoved, bcsid, employeeID);
            }
        }
    }
    
    private double calcVol(final FinishedGoodsInventory fgi, final int qty){
        PackageType pkg = fgi.getFGIPackageID();
        double retval = (double)qty * (double)pkg.getPackageTypeVol() * (double)fgi.getFGIPackageID().getNumItems();
        return retval;
    }
    
}
